#include "shader.hpp"

#include <Magick++/Image.h>
using namespace Magick;

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
using namespace Assimp;

#include <GL/glew.h>

#include <GL/glfw.h>

#include <string.h>

#include <iostream>
using namespace std;

#include <glm/glm.hpp>
using namespace glm;

class Material{
public:
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    uint texture;
    bool textured;

    Material();
};

class WavefrontOBJ {
private:
    static uint programID;

	static uint MatrixID;
	static uint ViewMatrixID;
	static uint ModelMatrixID;

	static uint LightID;
	static uint secLightID;
	static uint TextureID;

    static uint ambientID;
	static uint diffuseID;
	static uint specularID;

	static uint flagID;

	bool loaded;

    bool texture;
	bool noise;

    bool light;
    bool cameraLight;

	string path;
    string name;

	mat4 ModelMatrix;

	uint *vertexBuffer;
    uint *UVBuffer;
    bool *hasUV;
    uint *normalBuffer;
    bool *hasNormal;

    uint *bufferSize;

    uint *indicies;
    uint *indiciesSize;
    bool *hasFaces;

    uint *textureIndex;

	uint numMeshes;

    Material *material;
	uint numMaterial;

	bool loadWavefrontOBJ(const char* _path);

	bool initVertexBuffer(aiVector3D *mVertices, uint mNumVertices, uint vbn);
	bool initUVBuffer(aiVector3D *mUv, uint mNumUv, uint uvn);
	bool initNormalBuffer(aiVector3D *mNormal, uint mNumNormal, uint non);
    bool initFaceBuffer(aiFace *mFaces, uint mNumFaces, uint fan);

    bool initMaterial(aiMaterial *material, uint tn);
    bool loadTexture(string path, uint tn);

    bool initTextureIndex(uint mMaterialIndex, int ms);

    int createFlag(Material *material);

	bool loadProgram();
public:
    WavefrontOBJ(string _path, string _name);

    void lightChange();
    void cameraLightChange();
    void noiseChange();
    void textureChange();

    bool draw(mat4 _VP, mat4 _V, vec3 camerePosition);
};
